package com.gosophia.dataDictionary.ws.test.integration;

import java.util.List;

import junit.framework.Assert;

import org.hibernate.SessionFactory;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests;
import org.springframework.test.context.transaction.TransactionConfiguration;
import org.springframework.transaction.annotation.Transactional;

import com.gosophia.commons.Page;
import com.gosophia.commons.exception.BusinessException;
import com.gosophia.commons.exception.CommonException;
import com.gosophia.dataDictionary.dto.DataEntryDTO;
import com.gosophia.dataDictionary.dto.DataValueDTO;
import com.gosophia.dataDictionary.entity.DataEntry;
import com.gosophia.dataDictionary.entity.DataValue;
import com.gosophia.dataDictionary.ws.DataDictionaryWebService;

@ContextConfiguration(locations = { "classpath*:moduleContext.xml",
        "classpath:applicationContext-it.xml" })
@Transactional
@TransactionConfiguration(defaultRollback = true)
public class ITDataDictionaryWebServiceImpl extends
        AbstractTransactionalJUnit4SpringContextTests {

    @Autowired
    private DataDictionaryWebService dataDictionaryWebService;

    @Autowired
    private SessionFactory sf;

    @Test(expected = IllegalArgumentException.class)
    public void testAddDataValueWithNull() throws CommonException,
            BusinessException {
        dataDictionaryWebService.addDataValue(null, null);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testAddDataValueWithDataValueIdNotNull()
            throws CommonException, BusinessException {
        DataValueDTO dataValueDTO = new DataValueDTO();
        dataValueDTO.setDataValueId(1L);
        dataDictionaryWebService.addDataValue(dataValueDTO, null);
    }

    @Test(expected = BusinessException.class)
    public void testAddDataValueWithSameValue() throws CommonException,
            BusinessException {
        DataValueDTO dataValueDTO = new DataValueDTO();
        dataValueDTO.setValue("男");
        dataValueDTO.setEntryId(1016L);
        dataValueDTO.setIsEnabled(true);
        dataValueDTO.setKey("101");
        dataDictionaryWebService.addDataValue(dataValueDTO, null);
    }

    @Test(expected = BusinessException.class)
    public void testAddDataValueWithSameKey() throws CommonException,
            BusinessException {
        DataValueDTO dataValueDTO = new DataValueDTO();
        dataValueDTO.setValue("Man");
        dataValueDTO.setEntryId(1016L);
        dataValueDTO.setIsEnabled(true);
        dataValueDTO.setKey("001");
        dataDictionaryWebService.addDataValue(dataValueDTO, null);
    }

    @Test
    public void testAddDataValue() throws CommonException, BusinessException {
        DataValueDTO dataValueDTO = new DataValueDTO();
        dataValueDTO.setValue("abc");
        dataValueDTO.setEntryId(1016L);
        dataValueDTO.setIsEnabled(true);
        dataValueDTO.setKey("abc");
        dataDictionaryWebService.addDataValue(dataValueDTO, null);

        List<DataValue> dvs = sf.getCurrentSession().createQuery(
                "from DataValue d where d.dataEntry.entryId = 1016L order by d.orderIndex desc").list();
        Assert.assertEquals(3, dvs.size());
        Assert.assertEquals("abc", dvs.get(0).getValue());
        Assert.assertEquals(3, dvs.get(0).getOrderIndex());
    }

    @Test(expected = IllegalArgumentException.class)
    public void testUpdateDataValueWithNull() throws CommonException,
            BusinessException {
        dataDictionaryWebService.updateDataValue(null);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testUpdateDataValueWithDataValueIdNull()
            throws CommonException, BusinessException {
        DataValueDTO dataValueDTO = new DataValueDTO();
        dataValueDTO.setValue("aaa");
        dataDictionaryWebService.updateDataValue(dataValueDTO);
    }

    @Test(expected = BusinessException.class)
    public void testUpdateDataValueWithSameValue() throws CommonException,
            BusinessException {
        DataValueDTO dataValueDTO = new DataValueDTO();
        dataValueDTO.setDataValueId(1032L);
        dataValueDTO.setValue("男");
        dataValueDTO.setOrderIndex(2);
        dataValueDTO.setIsEnabled(true);
        dataValueDTO.setKey("002");
        dataValueDTO.setEntryId(1016L);
        dataDictionaryWebService.updateDataValue(dataValueDTO);
    }

    @Test(expected = BusinessException.class)
    public void testUpdateDataValueWithSameKey() throws CommonException,
            BusinessException {
        DataValueDTO dataValueDTO = new DataValueDTO();
        dataValueDTO.setDataValueId(1032L);
        dataValueDTO.setValue("M");
        dataValueDTO.setOrderIndex(2);
        dataValueDTO.setIsEnabled(true);
        dataValueDTO.setKey("001");
        dataValueDTO.setEntryId(1016L);
        dataDictionaryWebService.updateDataValue(dataValueDTO);
    }

    @Test
    public void testUpdateDataValue() throws CommonException, BusinessException {
        DataValueDTO dataValueDTO = new DataValueDTO();
        dataValueDTO.setDataValueId(1032L);
        dataValueDTO.setValue("Female");
        dataValueDTO.setOrderIndex(2);
        dataValueDTO.setIsEnabled(true);
        dataValueDTO.setKey("002");
        dataValueDTO.setEntryId(1016L);
        dataValueDTO.setVersion(0L);
        dataDictionaryWebService.updateDataValue(dataValueDTO);

        DataValue dv = (DataValue) sf.getCurrentSession().get(DataValue.class,
                1032L);
        Assert.assertEquals("Female", dv.getValue());
    }

    @Test(expected = IllegalArgumentException.class)
    public void testFindDataValueByEntryIdAndKeyWithEntryIdNull() {
        dataDictionaryWebService.findDataValueByEntryIdAndKey(null, "001");
    }

    @Test(expected = IllegalArgumentException.class)
    public void testFindDataValueByEntryIdAndKeyWithKeyNull() {
        dataDictionaryWebService.findDataValueByEntryIdAndKey(100L, null);
    }

    @Test
    public void testFindDataValueByEntryIdAndKey() {
        DataValueDTO dataValueDTO = dataDictionaryWebService
                .findDataValueByEntryIdAndKey(1016L, "001");
        Assert.assertEquals("男", dataValueDTO.getValue());
    }

    @Test(expected = IllegalArgumentException.class)
    public void testFindEnabledDataValueByEntryIdWithEntryIdNull() {
        dataDictionaryWebService.findEnabledDataValueByEntryId(null);
    }

    @Test
    public void testFindEnabledDataValueByEntryId() {
        List<DataValueDTO> dataValueDTOs = dataDictionaryWebService
                .findEnabledDataValueByEntryId(1025L);
        Assert.assertEquals(9, dataValueDTOs.size());
    }

    @Test(expected = IllegalArgumentException.class)
    public void testFindEntriesByPageWithPageNoLess0() {
        dataDictionaryWebService.findEntriesByPage(0, 1, "", null);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testFindEntriesByPageWithPageSizeLess0() {
        dataDictionaryWebService.findEntriesByPage(1, 0, "", null);
    }

    @Test
    public void testFindEntriesByPageWithNoCondition() {

        Page<DataEntryDTO> page = dataDictionaryWebService.findEntriesByPage(1,
                10, "", null);
        Assert.assertEquals(20, page.getTotalCount());

    }

    @Test
    public void testFindEntriesByPageWithCondition() {
        Page<DataEntryDTO> page = dataDictionaryWebService.findEntriesByPage(1,
                10, "gong", null);
        Assert.assertEquals(4, page.getResult().size());
    }

    /**
     * 测试findDataValueByEntryNameAndKey方法，当entryName为null时
     */
    @Test(expected = IllegalArgumentException.class)
    public void testFindDataValueByEntryNameAndKeyWithEntryNameNull() {
        dataDictionaryWebService.findDataValueByEntryNameAndKey(null, "001");
    }

    /**
     * 测试findDataValueByEntryNameAndKey方法，当key为null时
     */
    @Test(expected = IllegalArgumentException.class)
    public void testFindDataValueByEntryNameAndKeyWithKeyNull() {
        dataDictionaryWebService.findDataValueByEntryNameAndKey("sex", null);
    }

    /**
     * 测试findDataValueByEntryNameAndKey方法
     */
    @Test
    public void testFindDataValueByEntryNameAndKeyNormal() {
        DataValueDTO dataValueDTO = dataDictionaryWebService
                .findDataValueByEntryNameAndKey("sex", "001");
        Assert.assertEquals("男", dataValueDTO.getValue());
    }

    /**
     * 测试findEnabledDataValueByEntryName方法,当entryName为null时
     */
    @Test(expected = IllegalArgumentException.class)
    public void testFindEnabledDataValueByEntryNameWithEntryNameNull() {
        dataDictionaryWebService.findEnabledDataValueByEntryName(null);
    }

    /**
     * 测试findEnabledDataValueByEntryName方法
     */
    @Test
    public void testFindEnabledDataValueByEntryName() {
        List<DataValueDTO> dataValueDTOs = dataDictionaryWebService
                .findEnabledDataValueByEntryName("sex");
        Assert.assertEquals(1, dataValueDTOs.size());
        Assert.assertEquals("女", dataValueDTOs.get(0).getValue());
    }

    /**
     * 测试removeDataValue方法，当实体为null时
     * 
     * @throws BusinessException
     * @throws CommonException
     */
    @Test(expected = IllegalArgumentException.class)
    public void testRemoveDataValueByEntityWithNull() throws CommonException,
            BusinessException {
        dataDictionaryWebService.removeDataValue(null);
    }

    /**
     * 测试removeDataValue方法
     * 
     * @throws BusinessException
     * @throws CommonException
     */
    @Test
    public void testRemoveDataValueByEntity() throws CommonException,
            BusinessException {
        DataValueDTO dataValueDTO = new DataValueDTO();
        dataValueDTO.setDataValueId(1043L);
        dataValueDTO.setEntryId(1025L);
        dataValueDTO.setIsEnabled(true);
        dataValueDTO.setKey("DONG");
        dataValueDTO.setOrderIndex(11);
        dataValueDTO.setValue("侗族");
        dataValueDTO.setVersion(1L);
        dataDictionaryWebService.removeDataValue(dataValueDTO);
        sf.getCurrentSession().clear();

        DataValue dv = (DataValue) sf.getCurrentSession().get(DataValue.class,
                1043L);
        Assert.assertEquals(null, dv);
    }

    /**
     * 测试findDataEntryByDataEntryId
     */
    @Test
    public void testFindDataEntryByDataEntryIdNormal() {
        DataEntryDTO dataEntryDTO = dataDictionaryWebService
                .findDataEntryByDataEntryId(1016L);

        Assert.assertEquals("性别", dataEntryDTO.getEntryNameCN());
        Assert.assertEquals("sex", dataEntryDTO.getEntryDescliption());
        Assert.assertEquals(2, dataEntryDTO.getDataValues().size());

    }

    /**
     * 测试findDataEntryByDataEntryId:dataEntryId为null
     */
    @Test(expected = IllegalArgumentException.class)
    public void testFindDataEntryByDataEntryIdDataEntryIdNull() {
        dataDictionaryWebService.findDataEntryByDataEntryId(null);
    }

    /**
     * 测试findDataValueByDataValueId方法
     */
    @Test
    public void testFindDataValueByDataValueIdNormal() {
        DataValueDTO dataValueDTO = dataDictionaryWebService
                .findDataValueByDataValueId(1031L);
        Assert.assertEquals("男", dataValueDTO.getValue());
        Assert.assertEquals("001", dataValueDTO.getKey());
    }

    /**
     * 测试findDataValueByDataValueId方法:dataValueId为null
     */
    @Test(expected = IllegalArgumentException.class)
    public void testFindDataValueByDataValueIdNull() {
        dataDictionaryWebService.findDataValueByDataValueId(null);
    }

    /**
     * 测试moveDataValue方法，当fromId为null时
     */
    @Test(expected = IllegalArgumentException.class)
    public void testMoveDataValueWhenFromIdNull() {
        dataDictionaryWebService.moveDataValue(null, 1033L, 1025L);
    }

    /**
     * 测试moveDataValue方法，当entryId为null时
     */
    @Test(expected = IllegalArgumentException.class)
    public void testMoveDataValueWhenEntryIdNull() {
        dataDictionaryWebService.moveDataValue(1038L, 1033L, null);
    }

    /**
     * 测试moveDataValue方法
     */
    @Test
    public void testMoveDataValueNormal() {
        dataDictionaryWebService.moveDataValue(1038L, 1033L, 1025L);
        DataEntry de = (DataEntry) sf.getCurrentSession().get(DataEntry.class,
                1025L);
        List<DataValue> dvs = de.getDataValues();
        Assert.assertEquals("彝族", dvs.get(11).getValue());
        Assert.assertEquals(1, dvs.get(11).getOrderIndex());
        Assert.assertEquals("汉族", dvs.get(10).getValue());
        Assert.assertEquals(2, dvs.get(10).getOrderIndex());
    }

}
